from fastapi import APIRouter, status
from tortoise.query_utils import Prefetch
from blog.models import Tag, Tag_Py, TagIn_Py, Article ,Article_Py
from tortoise import exceptions, queryset
from tortoise.functions import Count
from fastapi.responses import JSONResponse
from tortoise.contrib.fastapi import HTTPNotFoundError
from typing import List


router = APIRouter(prefix="/tags", tags=["tag"])

class Tag_with_Article_Counter_Py(Tag_Py):
    article_amt: int

@router.get("/", response_model=List[Tag_with_Article_Counter_Py])
async def get_tags():
    qs = Tag.all().prefetch_related(Prefetch("articles", queryset=Article.all())).annotate(article_amt=Count("articles")).order_by("-article_amt")
    return await Tag_with_Article_Counter_Py.from_queryset(qs)


@router.post("/", response_model=Tag_Py)
async def create_tag(tag: TagIn_Py):
    try:
        tag_obj = await Tag.create(**tag.dict(exclude_unset=True))
    except exceptions.IntegrityError as e:
        # 详细错误信息可以记录到日志，e.args[0].as_dict()
        return JSONResponse(content={"error": "duplicated"},  status_code=status.HTTP_400_BAD_REQUEST)
    return await Tag_Py.from_tortoise_orm(tag_obj)


@router.put("/{id}/", response_model=Tag_Py, responses={404: {"model": HTTPNotFoundError}})
async def udpate_tag(id: int, tag: TagIn_Py):
    try:
        await Tag.get(id=id).update(**tag.dict(exclude_unset=True)) #直接生成一个更新语句不会产生404异常
    except exceptions.IntegrityError as e:
        return JSONResponse(content={"error": "duplicated"},  status_code=status.HTTP_400_BAD_REQUEST)

    try:
        return await Tag_Py.from_queryset_single(Tag.get(id=id))
    except exceptions.DoesNotExist as e:
        return JSONResponse(content={"error": "tag not found"},  status_code=status.HTTP_404_NOT_FOUND)


@router.delete("/{id}/")
async def delete_tag(id: int):
    await Tag.get(id=id).delete()

